package com.littleken.foodieCommon.Response;

import java.io.Serializable;
import java.util.Objects;

/*
 * Create by littleken on 2020/11/16 10:51
 */
public class ServerResponse<T> implements Serializable {

    //每一个微服务模块最好定义一个自己的错误代码静态类，并且从200000开始编码，0表示正确
    public static final ServerResponse<Object> INTERNAL_ERROR = new ServerResponse<>(500, "服务内部错误");
    public static final ServerResponse<Object> HYSTRIX_ERROR = new ServerResponse<>(999, "服务内部错误");
    public static final ServerResponse<Object> SUCCESS_RESPONSE = new ServerResponse<>();
    private static final long serialVersionUID = 1L;
    private int errcode;
    private String errmsg;
    private T data;

    private String detailErrMsg; //详细错误信息
    //可以用在zipkin界面检索服务链路
    private String hint; //实际上是traceid

    public ServerResponse() {

    }

    public ServerResponse(int errCode, String msg, String detailErrMsg) {
        this.errcode = errCode;
        this.errmsg = msg;
        this.detailErrMsg = detailErrMsg;
    }

    public ServerResponse(int errCode, String msg) {
        this(errCode, msg, "");
    }

    public ServerResponse(T data) {
        errcode = 0;
        errmsg = "";
        setData(data);
    }

    public ServerResponse(IErrorCode errorCode) {
        errcode = errorCode.getCode();
        errmsg = errorCode.getDscr();
    }

    /**
     * 无业务数据的成功响应
     */
    public static <T> ServerResponse<T> success() {
        return new ServerResponse<>(ErrorCode.SUCCESS);
    }

    /**
     * 带业务数据的成功响应
     *
     * @param data
     * @param <T>
     * @return
     */
    public static <T> ServerResponse<T> success(T data) {
        return success(data, ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getDscr());
    }


    /**
     * 带业务数据的成功响应
     *
     * @param data
     * @param <T>
     * @return
     */
    public static <T> ServerResponse<T> success(T data, String msg) {
        return success(data, ErrorCode.SUCCESS.getCode(), msg);
    }

    /**
     * 带业务数据的成功响应
     *
     * @param data
     * @param <T>
     * @return
     */
    public static <T> ServerResponse<T> success(T data, int code, String msg) {
        ServerResponse<T> response = new ServerResponse<T>();
        response.setErrcode(code);
        response.setErrmsg(msg);
        response.setData(data);
        return response;
    }

    /**
     * 响应失败
     *
     * @return
     */
    public static <T> ServerResponse<T> fail() {
        return fail(ErrorCode.INTERNAL_ERR.getCode(), ErrorCode.INTERNAL_ERR.getDscr());
    }

    /**
     * 响应失败
     *
     * @param responseCode
     * @return
     */
    public static <T> ServerResponse<T> fail(IErrorCode responseCode) {
        return fail(responseCode.getCode(), responseCode.getDscr());
    }

    /**
     * 响应失败
     *
     * @param failCode
     * @param msg
     * @return
     */
    public static <T> ServerResponse<T> fail(int failCode, String msg) {
        ServerResponse<T> response = new ServerResponse<T>();
        response.setErrcode(failCode);
        response.setErrmsg(msg);
        return response;
    }

    /**
     * 响应失败
     */
    public static <T> ServerResponse<T> fail(IErrorCode responseCode, String detailErrMsg) {
        ServerResponse<T> response = new ServerResponse<T>();
        response.setErrcode(responseCode.getCode());
        response.setErrmsg(responseCode.getDscr());
        response.setDetailErrMsg(detailErrMsg);
        return response;
    }

    /**
     * 响应失败
     *
     * @param data 响应出错的数据
     * @param failCode
     * @param msg
     * @return
     */
    public static <T> ServerResponse<T> fail(T data, int failCode, String msg) {
        ServerResponse<T> response = new ServerResponse<T>();
        response.setErrcode(failCode);
        response.setErrmsg(msg);
        response.setData(data);
        return response;
    }

    public static boolean isSuccess(ServerResponse serverResponse) {
        return Objects.nonNull(serverResponse) && 0 == serverResponse.getErrcode();
    }

    public int getErrcode() {
        return errcode;
    }

    public void setErrcode(int errcode) {
        this.errcode = errcode;
    }

    public String getErrmsg() {
        return errmsg;
    }

    public void setErrmsg(String errmsg) {
        this.errmsg = errmsg;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    public String getDetailErrMsg() {
        return detailErrMsg;
    }

    public void setDetailErrMsg(String detailErrMsg) {
        this.detailErrMsg = detailErrMsg;
    }

    public String getHint() {
        return hint;
    }

    public void setHint(String hint) {
        this.hint = hint;
    }

    @Override
    public String toString() {
        return "ServerResponse{" +
                "errcode=" + errcode +
                ", errmsg='" + errmsg + '\'' +
                ", data=" + data +
                ", detailErrMsg='" + detailErrMsg + '\'' +
                ", hint='" + hint + '\'' +
                '}';
    }
}